package org.origin.centre.utils;

import org.springframework.data.redis.core.RedisTemplate;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 系统Redis缓存工具类，提供对Redis操作的封装。
 *
 * @author ferret
 * @version 2024-05-08
 */
@SuppressWarnings("ALL")
public final class RedisUtil {

    private static volatile RedisTemplate<String, Object> redisTemplate;

    private RedisUtil() {
        throw new AssertionError("Utility class cannot be instantiated.");
    }

    /**
     * 获取RedisTemplate实例。
     *
     * @return RedisTemplate实例
     */
    public static RedisTemplate<String, Object> getRedisTemplate() {
        if (redisTemplate == null) {
            synchronized (RedisUtil.class) {
                if (redisTemplate == null) {
                    redisTemplate = SpringUtil.getBean("redisTemplate", RedisTemplate.class);
                }
            }
        }
        return redisTemplate;
    }

    /**
     * 设置键值对到Redis。
     *
     * @param key   键
     * @param value 值
     */
    public static void set(String key, Object value) {
        getRedisTemplate().opsForValue().set(key, value);
    }

    /**
     * 设置键值对到Redis，并指定过期时间。
     *
     * @param key     键
     * @param value   值
     * @param timeout 过期时间
     * @param unit    时间单位
     */
    public static boolean set(String key, Object value, long timeout, TimeUnit unit) {
        return getRedisTemplate().opsForValue().setIfAbsent(key, value, timeout, unit);
    }

    /**
     * 从Redis获取键对应的值。
     *
     * @param key 键
     * @return 对应的值
     */
    public static Object get(String key) {
        return getRedisTemplate().opsForValue().get(key);
    }

    /**
     * 从Redis删除键。
     *
     * @param key 键
     */
    public static void delete(String key) {
        getRedisTemplate().delete(key);
    }

    /**
     * 批量删除Redis中的多个键。
     *
     * @param keys 键的集合
     */
    public static void delete(Collection<String> keys) {
        getRedisTemplate().delete(keys);
    }

    /**
     * 检查Redis中是否存在给定的键。
     *
     * @param key 键
     * @return 是否存在
     */
    public static boolean exists(String key) {
        return getRedisTemplate().hasKey(key);
    }

    /**
     * 向Redis列表的头部添加元素。
     *
     * @param key   列表键
     * @param value 元素
     */
    public static void leftPush(String key, Object value) {
        getRedisTemplate().opsForList().leftPush(key, value);
    }

    /**
     * 从Redis列表的头部弹出元素。
     *
     * @param key 列表键
     * @return 弹出的元素
     */
    public static Object leftPop(String key) {
        return getRedisTemplate().opsForList().leftPop(key);
    }

    /**
     * 向Redis集合添加元素。
     *
     * @param key   集合键
     * @param value 元素
     */
    public static void addSet(String key, Object value) {
        getRedisTemplate().opsForSet().add(key, value);
    }

    /**
     * 获取Redis集合的所有元素。
     *
     * @param key 集合键
     * @return 集合中的所有元素
     */
    public static Set<Object> membersOfSet(String key) {
        return getRedisTemplate().opsForSet().members(key);
    }

    /**
     * 在Redis哈希表中设置字段和值。
     *
     * @param key   哈希表键
     * @param field 字段
     * @param value 值
     */
    public static void setHash(String key, String field, Object value) {
        getRedisTemplate().opsForHash().put(key, field, value);
    }

    /**
     * 从Redis哈希表中获取字段的值。
     *
     * @param key   哈希表键
     * @param field 字段
     * @return 字段的值
     */
    public static Object getFromHash(String key, String field) {
        return getRedisTemplate().opsForHash().get(key, field);
    }

    /**
     * 获取Redis哈希表中的所有字段和值。
     *
     * @param key 哈希表键
     * @return 包含所有字段和值的Map
     */
    public static Map<Object, Object> entriesOfHash(String key) {
        return getRedisTemplate().opsForHash().entries(key);
    }
}

